package me.leiusual.sharing.ui.mine.adapter

import android.content.Context
import android.widget.ArrayAdapter
import android.widget.Filter
import io.reactivex.disposables.Disposable
import io.reactivex.observers.DisposableSingleObserver
import me.leiusual.sharing.api.model.AddressRegion
import me.leiusual.sharing.repository.AddressRepository
import timber.log.Timber

/**
 * author: leiusual
 * create on: 2019-07-29
 * description:
 */
class MineAddressEditAdapter(
    context: Context, resource: Int
) : ArrayAdapter<AddressRegion>(context, resource) {

  private val dataSet = mutableListOf<AddressRegion>()

  lateinit var addressRepository: AddressRepository

  @Volatile
  private var disposable: Disposable? = null

  override fun getCount(): Int {
    return dataSet.size
  }

  override fun getItem(position: Int): AddressRegion? {
    return dataSet[position]
  }

  override fun getFilter(): Filter {
    Timber.v("getFilter")
    return object : Filter() {

      override fun performFiltering(constraint: CharSequence?): FilterResults {
        Timber.v("performFiltering constraint = %s", constraint)
        val filterResults = FilterResults()

        disposable?.dispose()
        if (constraint != null) {
          disposable = addressRepository.addressRegionQuery(constraint.toString())
              .subscribeWith(object : DisposableSingleObserver<Map<Long, String>>() {
                override fun onError(e: Throwable) {
                  Timber.w(e)
                }

                override fun onSuccess(t: Map<Long, String>) {
                  dataSet.addAll(t.entries.map {
                    AddressRegion(it.key, it.value)
                  })
                  filterResults.values = dataSet
                  filterResults.count = dataSet.size
                }
              })
        }

        return filterResults
      }

      override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
        Timber.v("publishResults constraint = %s", constraint)
        if (results != null && results.count > 0) {
          notifyDataSetChanged()
        } else {
          notifyDataSetInvalidated()
        }
      }
    }
  }

  fun cancel() {
    disposable?.dispose()
  }
}